#ifndef WEAPON
#define WEAPON

#include "Class Manager.h"
#include "Dark.h"
#include "BJ.h"
#include "Weapon Type.h"

class Weapon
{
    public :

        Weapon
        (
            WeaponType *iPWeaponType,
            double      iXOrigin,
            double      iYOrigin,
            double      iAngle
        )
        {
            _pWeaponType        = iPWeaponType;
            _offsetAngle        = dbATANFULL(iYOrigin,iXOrigin);
            _offsetDistance     = sqrt((iXOrigin * iXOrigin) + (iYOrigin * iYOrigin));
            _angle              = iAngle;
            _cooldownRemaining  = 0;
            _energy             = 0;
        }

        ~Weapon
        (
            void
        )
        {
        }
          
        bool Refresh
        (
            double &iREnergy
        )
        {
            double energyToTransfer = BJ_min(_pWeaponType->_energyCap - _energy,BJ_min(_pWeaponType->_energyTransferRate,iREnergy));
            _energy += energyToTransfer;
            iREnergy -= energyToTransfer;
            _cooldownRemaining = BJ_max(0,_cooldownRemaining - 1);
            return true;
        }
        
        bool Shoot
        (
            Ship        *iShip,
            Point       *iLocation,
            double       iRotation,
            double       iXVelocity,
            double       iYVelocity
        )
        {
                if ((_energy >= _pWeaponType->_energyCost) & (_cooldownRemaining == 0))
                {
                    _energy -= _pWeaponType->_energyCost; // This may be instead implemented as module energy cost.
                    _cooldownRemaining = _pWeaponType->_cooldown;
                    Projectile *projectile = ProjectileManager.create();
                    double rotation     = _angle + iRotation;
                    double speed        = _pWeaponType->_velocity;
                    double xVelocity    = iXVelocity + (speed*dbCos(rotation));
                    double yVelocity    = iYVelocity + (speed*dbSin(rotation));
                    double xStart       = iLocation->x() + (_offsetDistance * dbCos(iRotation + _offsetAngle));
                    double yStart       = iLocation->y() + (_offsetDistance * dbSin(iRotation + _offsetAngle));
                    //                                                                          , duration       ,scale, mass,damage,image,owner
                    projectile->Init(xStart,yStart,xVelocity,yVelocity,rotation  ,2*Dark::BASE_FPS,_pWeaponType->_radius,_pWeaponType->_mass,_pWeaponType->_damage,_pWeaponType->_pImage->image_id(),iShip);
                }
                else
                {
                    // Cannot shoot
                    return false;
                }
            return true;
        }
          
    private: 
    
    // May be part of modules rather than ships later.
    
    WeaponType *_pWeaponType        ;
    double      _offsetAngle        ;
    double      _offsetDistance     ;
    double      _angle              ;
    int         _cooldownRemaining  ;
    double      _energy             ;
};
ObjectManager<Weapon> WeaponManager;
#endif